package com.vesystem.vegua.modules.common.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vesystem.vegua.config.GlobalConfig;
import com.vesystem.vegua.config.ServerListener;
import com.vesystem.vegua.exceptionConfig.ErrorCode;
import com.vesystem.vegua.exceptionConfig.ParameterInvalid;
import com.vesystem.vegua.modules.common.controller.RemoteAppController;
import com.vesystem.vegua.modules.common.dto.MonitoringFileDto;
import com.vesystem.vegua.modules.common.dto.RemoteAppDto;
import com.vesystem.vegua.modules.common.dto.SysIconDto;
import com.vesystem.vegua.modules.common.entity.*;
import com.vesystem.vegua.modules.common.mapper.*;
import com.vesystem.vegua.modules.common.service.IRemoteAppService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vesystem.vegua.utils.JwtToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hcy
 * @since 2020-12-08
 */
@Service
public class RemoteAppServiceImpl extends ServiceImpl<RemoteAppMapper, RemoteApp> implements IRemoteAppService {

    private static Logger log = LoggerFactory.getLogger(RemoteAppController.class);

    @Autowired
    private RemoteAppMapper remoteAppMapper;
    @Autowired
    private MappingUserAppMapper mappingUserAppMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysIconMapper sysIconMapper;
    @Autowired
    private RemoteMonitoringMapper remoteMonitoringMapper;
    @Autowired
    private ServersMonitoringMapper serversMonitoringMapper;


    public void addApp(RemoteAppDto remoteApp){
        QueryWrapper<RemoteApp> qw = new QueryWrapper<>();
        qw.eq("remote_ip",remoteApp.getRemoteIp()).eq("remote_port",remoteApp.getRemotePort())
                .eq("protocol",remoteApp.getProtocol()).eq("app_path",remoteApp.getAppPath())
                .eq("remote_loginname",remoteApp.getRemoteLoginname());
        RemoteApp dbApp = remoteAppMapper.selectOne(qw);
        if ( !Objects.isNull( dbApp )){
            throw new ParameterInvalid(ErrorCode.DATA_ALERADY_EXIST);
        }
        remoteApp.setId(null);
        remoteAppMapper.insert( remoteApp );

        QueryWrapper<ServersMonitoring> qw_serv = new QueryWrapper<>();
        qw_serv.eq("serv_ip",remoteApp.getRemoteIp()).eq("serv_port",remoteApp.getRemotePort());
        ServersMonitoring db_ser = serversMonitoringMapper.selectOne(qw_serv);
        if ( db_ser == null ){
            ServersMonitoring serversMonitoring = new ServersMonitoring();
            serversMonitoring.setServIp( remoteApp.getRemoteIp() );
            //默认9010端口
            serversMonitoring.setServPort( 9010 );
            serversMonitoring.setServName( remoteApp.getRemoteAlias() );
            serversMonitoring.setServDesc( "由系统自动映射的服务列表" );
            serversMonitoringMapper.insert(serversMonitoring);
        }
    }

    public RemoteApp getRemoteAppInfoById(Integer appId){
         RemoteApp dbApp = remoteAppMapper.selectById(appId);
        if ( Objects.isNull( dbApp ) ){
            throw new ParameterInvalid(ErrorCode.DATA_NOT_EXIST);
        }
        return dbApp;
    }

    public void updateRemoteApp(RemoteAppDto remoteApp){
        RemoteApp dbApp = remoteAppMapper.selectById(remoteApp.getId());
        if ( Objects.isNull( dbApp ) ){
            throw new ParameterInvalid(ErrorCode.DATA_NOT_EXIST);
        }
        remoteAppMapper.updateById(remoteApp);
    }

    public void deleteRemoteAppById(Integer appId){
        RemoteApp dbApp = remoteAppMapper.selectById(appId);
        if ( Objects.isNull( dbApp ) ){
            throw new ParameterInvalid(ErrorCode.DATA_NOT_EXIST);
        }
        QueryWrapper<MappingUserApp> qw = new QueryWrapper<>();
        qw.eq("app_id",appId);
        MappingUserApp mappingUserApp = mappingUserAppMapper.selectOne(qw);
        if ( !Objects.isNull( mappingUserApp ) ){
            throw new ParameterInvalid(ErrorCode.NOT_DELETE_APP_BECAUSE_MAPPING_USER);
        }
        remoteAppMapper.deleteById(appId);
    }

    public Page<RemoteApp> adminGetAllRemoteAppList(Page<RemoteApp> page,String appName,String serverIp){
        QueryWrapper<RemoteApp> qw = new QueryWrapper<>();
        qw.like("remote_alias",appName).like("remote_ip",serverIp);
        return remoteAppMapper.selectPage(page,qw);
    }

    public List<RemoteApp> userGetRemoteAppList( HttpServletRequest request){
        String loginname = JwtToken.getUserLoginname(request);
        QueryWrapper<SysUser> qw = new QueryWrapper<>();
        qw.eq("loginname",loginname);
        SysUser dbUser = sysUserMapper.selectOne(qw);
        return mappingUserAppMapper.getAppListByUserId(dbUser.getId());
    }

    public void goToRemotePage(HttpServletRequest request, HttpServletResponse response,Integer remoteId,String token) throws IOException {
        String loginname = JwtToken.getUserLoginname(token);
        response.sendRedirect("/static/remote/index.html?sourceType=1&connectionParam="+remoteId+"&loginname="+loginname);
    }

    public Boolean checkUamToken(String token){
        Map<String,String> param = new HashMap<>();
        param.put("token",token);
        int statusCode = HttpRequest.post(GlobalConfig.EXTEND_UAM_CHECK_TOKEN_URL).header("Content-Type","application/x-www-form-urlencoded")
                .form("token",token).timeout(5000).execute().getStatus();
        return statusCode == 204;
    }

    public void uploadIcon(MultipartFile file){
        if ( file.isEmpty() ){
            throw new ParameterInvalid(ErrorCode.METHOD_ARGUMENT_NOT_VALID);
        }
        String uuid = UUID.randomUUID().toString();
        String fileName = file.getOriginalFilename();
        String suffixName = fileName.substring( fileName.lastIndexOf(".") );
        File icon = new File(GlobalConfig.BASE_PATH +
                GlobalConfig.BASE_PATH_ABOUT_ICON +uuid +suffixName  );
        try {
            System.out.println(icon.getPath());
            icon.createNewFile();
            file.transferTo( icon );
            sysIconMapper.insert(new SysIcon(uuid + suffixName));
        } catch (IOException e) {
            log.error(e.getLocalizedMessage(),e);
        }

    }

    public void deleteIcon(String  iconName){
        List<Integer> dbList = sysIconMapper.selectAppIdsByIconName(iconName);
        if ( dbList.size() != 0 ){
            throw new ParameterInvalid(ErrorCode.NOT_DELETE_ICON_BECAUSE_MAPPING_APP);
        }
        sysIconMapper.deleteById(iconName);
        File icon = new File(GlobalConfig.BASE_PATH +
                GlobalConfig.BASE_PATH_ABOUT_ICON +iconName   );
        icon.delete();
    }

    public Page<SysIconDto> getIconList(Page<SysIconDto> page){
        sysIconMapper.selectPageSysIconDto(page);
        List<SysIconDto> list =  page.getRecords();
        for ( SysIconDto icon:list ){
            icon.setIconUrl( "/appIcon/" +icon.getIconName()  );
        }
        return page;
    }

    public void updateAppIcon(List<Integer> appId,String iconUrl){
        if ( appId.size()>0){
            sysIconMapper.updateAppIcon(appId,iconUrl);
        }
    }

    public List<Integer> selectAppIdsByIconName(String iconName){
        return sysIconMapper.selectAppIdsByIconName(iconName);
    }

    public List<Integer> getAllRemoteMonitoringAppIds(){
        return remoteMonitoringMapper.selectAllMonitoringList();
    }

    public void updateRemoteMonitoringList(List<Integer> list){
        remoteMonitoringMapper.delete(new QueryWrapper<>());
        if ( list.size()>0 ){
            remoteMonitoringMapper.batchInsertAppIds(list);
        }
        ServerListener.REMOTE_MOITORING.clear();
        ServerListener.REMOTE_MOITORING.addAll(list);
    }

    public List<MonitoringFileDto> getMonitoringFileDtoList(String remoteAlias,Long startTime,Long endTime){
        if ( startTime ==null || endTime == null){
            throw new ParameterInvalid(ErrorCode.METHOD_ARGUMENT_NOT_VALID);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Integer st = Integer.parseInt(sdf.format(new Date(startTime)));
        Integer et = Integer.parseInt(sdf.format(new Date(endTime)));
        System.out.println( "参数："+remoteAlias + "startTime: "+ st + " endTime:"+et );
        List<MonitoringFileDto> list = new ArrayList<>();
        File rdpF = new File("/rdpVideo");
        if ( rdpF == null ){
            return list;
        }
        File[] files1= rdpF.listFiles();
        System.out.println( Arrays.toString(files1) );
        for (File f :files1){
            if ( f.isFile() ){
                String fname = f.getName();
                System.out.println( fname );
                Integer ft = Integer.valueOf(fname.substring(0,8));
                if ( StringUtils.isEmpty( remoteAlias ) && fname.contains(remoteAlias)){
                    System.out.println( "名称满足条件" );
                    if ( ft>=st && ft<= et){
                        System.out.println( "时间满足条件" );
                        MonitoringFileDto mfd = new MonitoringFileDto();
                        mfd.setFileName( f.getName() );
                        mfd.setFileSize( f.length() );
                        mfd.setProtocol("rdp");
                        list.add( mfd );
                    }
                }
            }
        }
        File sshF = new File("/sshVideo");
        File[] files2= sshF.listFiles();
        for (File f:files2){
            if ( f.isFile() && !f.getName().endsWith(".timing") ){
                String fname = f.getName();
                Integer ft = Integer.valueOf(fname.substring(0,8));
                if ( !fname.endsWith(".timing") ){
                    if ( fname.indexOf(remoteAlias)>0 ){
                        if ( ft>=st && ft<= et ){
                            MonitoringFileDto mfd = new MonitoringFileDto();
                            mfd.setFileName( f.getName() );
                            mfd.setFileSize( f.length() );
                            mfd.setProtocol("ssh");
                            list.add( mfd );
                        }
                    }
                }
            }
        }
        Collections.sort( list );
        return list;
    }















}
